/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ru.dusty.lab2.raid.utils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

/**
 *
 * @author vadim
 */
public class RaidConfig {
    
    private static final String CONFIG_FILE = "config";
    
    public static final int MIN_DISKS_COUNT = 1;
//    private static final int MAX_DISKS_COUNT = 5;
    
    public static final int MIN_BLOCKS_COUNT = 100;
    public static final int MAX_BLOCKS_COUNT = 10000;
    
    public static final int MIN_BLOCK_SIZE = 256;
    public static final int MAX_BLOCK_SIZE = 2048;
    
    public static final int MIN_RAID_LEVEL = 0;
    public static final int MAX_RAID_LEVEL = 5;
    
    private int disksCount;
    
    private int blocksCount;
    
    private int blockSize;
    
    private int raidLevel;
    
    private String root;
    
    public RaidConfig(String root) {
        this.root = root;
        loadDefaultConfig();
    }
    
    public void loadConfig() throws FileNotFoundException, IOException, NumberFormatException {
        File config = new File(root + File.separator + CONFIG_FILE);
        FileReader fr = new FileReader(config);
        BufferedReader reader = new BufferedReader(fr);
        
        try {
            disksCount = Integer.parseInt(parseLine(reader.readLine()));
            blocksCount = Integer.parseInt(parseLine(reader.readLine()));
            blockSize = Integer.parseInt(parseLine(reader.readLine()));
            raidLevel = Integer.parseInt(parseLine(reader.readLine()));
        } finally {
            reader.close();
            fr.close();
        }   
    }
    
    public void saveConfig() throws IOException {
        File config = new File(root + File.separator + CONFIG_FILE);
        FileWriter fw = new FileWriter(config);
        BufferedWriter writer = new BufferedWriter(fw);
        PrintWriter out = new PrintWriter(writer);
        
        out.println("disksCount=" + disksCount);
        out.println("blocksCount=" + blocksCount);
        out.println("blockSize=" + blockSize);
        out.println("raidLevel=" + raidLevel);
        out.flush();
    }
    
    private String parseLine(String line) {
        if (line == null) return null;
        
        int index = line.indexOf("=");
        
        if (index == -1 || (index + 1) == line.length()) return null;
        
        return line.substring(index + 1).trim();
    }
    
    public final void loadDefaultConfig() {
        disksCount = MIN_DISKS_COUNT;
        blocksCount = MIN_BLOCKS_COUNT;
        blockSize = MIN_BLOCK_SIZE;
        raidLevel = MIN_RAID_LEVEL;
    }
    
    public boolean checkConfig() {
        if (disksCount < MIN_DISKS_COUNT) {
            System.out.println("Disks count N should be greater than 0.");
            return false;
        }

        if (blocksCount < MIN_BLOCKS_COUNT || blocksCount > MAX_BLOCKS_COUNT) {
            System.out.println("Blocks count K should be in the range of "
                    + "from " + MIN_BLOCKS_COUNT + " to " + MAX_BLOCKS_COUNT + ".");
            return false;
        }

        if (blockSize < MIN_BLOCK_SIZE || blockSize > MAX_BLOCK_SIZE) {
            System.out.println("Block size M should be in the range of "
                    + "from " + MIN_BLOCK_SIZE + " to " + MAX_BLOCK_SIZE + ".");
            return false;
        }

        if (raidLevel < MIN_RAID_LEVEL || raidLevel > MAX_RAID_LEVEL || raidLevel == 2) {
            System.out.println("RAID level L should be in the range of "
                    + "from " + MIN_RAID_LEVEL + " to " + MAX_RAID_LEVEL + "(ex 2).");
            return false;
        }
        
        if ((raidLevel >= 3 && raidLevel <= 5) && disksCount < 2) {
            System.out.println("Minimum number of disks for a given RAID level - 2.");
            return false;
        }
        
        return true;
    }

    public int getBlockSize() {
        return blockSize;
    }

    public int getBlocksCount() {
        return blocksCount;
    }

    public int getDisksCount() {
        return disksCount;
    }

    public int getRaidLevel() {
        return raidLevel;
    }

    public void setBlockSize(int blockSize) {
        this.blockSize = blockSize;
    }

    public void setBlocksCount(int blocksCount) {
        this.blocksCount = blocksCount;
    }

    public void setDisksCount(int disksCount) {
        this.disksCount = disksCount;
    }

    public void setRaidLevel(int raidLevel) {
        this.raidLevel = raidLevel;
    }

    
}
